﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.ComponentModel;

namespace ScoringClient.Views
{
    /// <summary>
    /// Identification.xaml 的交互逻辑
    /// </summary>
    public partial class Identification : Window, INotifyPropertyChanged
    {
        private const int IDENTIFYING_CODE_LEN = 4;
        private string correctIdentifyingCode;

        #region Identifying Code
        private string identifyingCode;
        public string IdentifyingCode
        {
            get
            {
                return identifyingCode;
            }
            set
            {
                if (value == identifyingCode) return;
                identifyingCode = value;
                OnPropertyChanged("IdentifyingCode");
            }
        }
        #endregion

        #region Error Message
        private string errorMessage;
        public string ErrorMessage
        {
            get
            {
                return errorMessage;
            }
            set
            {
                if (value == errorMessage) return;
                errorMessage = value;
                OnPropertyChanged("ErrorMessage");
            }
        }
        #endregion

        #region Length of Identifying Code
        public int IdentifyingCodeLength
        {
            get
            {
                return IDENTIFYING_CODE_LEN;
            }
        }
        #endregion

        #region INotifyPropertyChanged 成员

        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

        public Identification()
        {
            InitializeComponent();
            txtIdentifyingCode.Focus();
            GenerateImage();
        }

        private void GenerateImage()
        {
            this.imgIdentifyingCode.Children.Clear();

            correctIdentifyingCode = Utilities.CreateRandomCode(IDENTIFYING_CODE_LEN).ToUpper();

            double heigth = this.imgIdentifyingCode.Height;
            double width = this.imgIdentifyingCode.Width;

            string[] fonts = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "Calibri" };
            Color[] colors = 
            { 
                Colors.Red, 
                Colors.Blue, 
                Colors.Chocolate, 
                Colors.BlueViolet, 
                Colors.CadetBlue, 
                Colors.Coral, 
                Colors.CornflowerBlue, 
                Colors.DarkBlue, 
                Colors.DeepPink,
                Colors.DimGray,
                Colors.Goldenrod,
                Colors.LightCoral,
                Colors.DarkOrange 
            };

            Random random = new Random();

            // 画布
            Rectangle background = new Rectangle();
            background.Fill = new SolidColorBrush(Colors.White);
            background.Width = width;
            background.Height = heigth;
            this.imgIdentifyingCode.Children.Add(background);

            // 噪点
            for (int i = 0; i < 300; i++)
            {
                Rectangle noisyPoint = new Rectangle();
                noisyPoint.Width = 1;
                noisyPoint.Height = 1;
                noisyPoint.Fill = new SolidColorBrush(Color.FromArgb(255, (byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255)));

                this.imgIdentifyingCode.Children.Add(noisyPoint);
                Canvas.SetLeft(noisyPoint, random.NextDouble() * width);
                Canvas.SetTop(noisyPoint, random.NextDouble() * heigth);
            }

            // 验证码
            double range = width / (correctIdentifyingCode.Length + 1);
            double maxRotate = 35;
            int direction = random.Next() % 2 == 0 ? 1 : -1;
            for (int i = 0; i < correctIdentifyingCode.Length; i++)
            {
                double rotate = random.NextDouble() * direction * maxRotate;
                TextBlock letter = new TextBlock();
                letter.Text = correctIdentifyingCode.Substring(i, 1);
                letter.RenderTransform = new RotateTransform(rotate);
                letter.FontFamily = new FontFamily(fonts[random.Next() % fonts.Length]);
                letter.FontSize = 26;
                letter.Foreground = new SolidColorBrush(Color.FromArgb(255, (byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255)));

                this.imgIdentifyingCode.Children.Add(letter);

                double l = (direction > 0 ? 15 : -3) + range * i;
                double t = 1;
                Canvas.SetLeft(letter, l);
                Canvas.SetTop(letter, t);
            }
        }

        private void imgIdentifyingCode_Click(object sender, MouseEventArgs e)
        {
            GenerateImage();
        }

        private void OK_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(IdentifyingCode))
            {
                this.ErrorMessage = Properties.Resources.IdentifyingCodeEmpty;
                return;
            }

            if (string.Equals(correctIdentifyingCode, IdentifyingCode, StringComparison.CurrentCultureIgnoreCase))
            {
                this.DialogResult = true;
            }
            else
            {
                this.ErrorMessage = Properties.Resources.IdentifyingCodeNotEqual;
            }

            IdentifyingCode = string.Empty;
            GenerateImage();
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }
    }
}
